﻿/**
* CRL
*/
#if NETSTANDARD 
using Microsoft.Extensions.DependencyInjection;
//using Microsoft.AspNetCore.Builder;
#endif
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Linq;

namespace CRL.EventBus.NetCore
{
#if NETSTANDARD 
    public static class EventBusExtensions
    {
        static Action<QueueConfig> _setupAction;
        static QueueConfig _queueConfig;
        /// <summary>
        /// ���EventBus
        /// </summary>
        /// <param name="services"></param>
        /// <param name="setupAction"></param>
        public static void AddEventBus(this IServiceCollection services, Action<QueueConfig> setupAction)
        {
            Action<QueueConfig> setupAction2 = b =>
            {
                b.fromNetCoreInjection = true;
            };
            setupAction += setupAction2;
            _setupAction = setupAction;
            services.Configure(setupAction);
            services.AddSingleton<IPublisher, Publisher>();
            services.AddSingleton<PublisherFactory>();
            _queueConfig = new QueueConfig();
            _setupAction(_queueConfig);
            //foreach (var s in _queueConfig.settings)
            //{
            //    switch (s.MQType)
            //    {
            //        case MQType.RabbitMQ:
            //            services.AddSingleton<Queue.RabbitMQPublisher>();
            //            break;
            //        case MQType.Redis:
            //            services.AddSingleton<Queue.RedisPublisher>();
            //            break;
            //        //case MQType.MongoDb:
            //        //    services.AddSingleton<Queue.MongoPublisher>();
            //        //    break;
            //        case MQType.Memory:
            //            services.AddSingleton<Queue.MemoryPublisher>();
            //            break;
            //        case MQType.Db:
            //            services.AddSingleton<Queue.DbPublisher>();
            //            break;
            //    }
            //}
            RegisterSubscribeService(services);
        }
        //[Obsolete]
        //public static void AddEventBusSubscribe(this IServiceCollection services)
        //{
        //}

        /// <summary>
        /// ��Ӷ���
        /// </summary>
        /// <param name="services"></param>
        static void RegisterSubscribeService(IServiceCollection services)
        {
            services.AddSingleton<SubscribeService>();
            //services.AddHostedService<SubscribeBackgroundService>();
            foreach (var assembyle in _queueConfig.SubscribeAssemblies)
            {
                var types = assembyle.GetTypes();
                foreach (var type in types)
                {
                    SubscribeService.Register(_queueConfig, type, true);
                    var atr = type.GetCustomAttribute(typeof(SubscribeAttribute));
                    if (atr != null)
                    {
                        services.AddScoped(type);
                    }
                }
            }
            SubscribeService.SetTypeRegistered();
            //services.AddHostedService<SubscribeBackgroundService>();
        }
        /// <summary>
        /// �������
        /// </summary>
        /// <param name="provider"></param>
        public static void RunEventBusSubscribe(this IServiceProvider provider)
        {
            var subscribeService = provider.GetService<SubscribeService>();
            subscribeService.StartSubscribe();
        }
        ///// <summary>
        ///// �������
        ///// </summary>
        ///// <param name="app"></param>
        //public static void RunEventBusSubscribe(this IApplicationBuilder app)
        //{
        //    app.ApplicationServices.RunEventBusSubscribe();
        //}
    }

    //class SubscribeBackgroundService : BackgroundService
    //{
    //    SubscribeService subscribeService;
    //    QueueConfig queueConfig;
    //    IServiceProvider serviceProvider;
    //    public SubscribeBackgroundService(Microsoft.Extensions.Options.IOptions<QueueConfig> options, SubscribeService _subscribeService, IServiceProvider _serviceProvider)
    //    {
    //        queueConfig = options.Value;
    //        subscribeService = _subscribeService;
    //        serviceProvider = _serviceProvider;
    //    }
    //    protected override Task ExecuteAsync(CancellationToken stoppingToken)
    //    {
    //        subscribeService.Register(queueConfig.SubscribeAssemblies);
    //        stoppingToken.Register(() =>
    //        {
    //            subscribeService.StopSubscribe();
    //        });

    //        subscribeService.StartSubscribe();
    //        return Task.CompletedTask;
    //    }
    //}
#endif
}
